package com.tansuo365.test1.util;

import org.springframework.cglib.beans.BeanMap;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

//BeanMapUtil类，PO到Map的转换方法，基于类反射技术：
public class BeanMapUtil {

    //in use
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static Map convertBean2Map(Object bean) throws Exception {
        Map returnMap = null;
        try {
            Class type = bean.getClass();
            returnMap = new HashMap();
            BeanInfo beanInfo = Introspector.getBeanInfo(type);
            PropertyDescriptor[] propertyDescriptors = beanInfo
                    .getPropertyDescriptors();
            for (int i = 0; i < propertyDescriptors.length; i++) {
                PropertyDescriptor descriptor = propertyDescriptors[i];
                String propertyName = descriptor.getName();
                if (!propertyName.equalsIgnoreCase("class")) {
                    Method readMethod = descriptor.getReadMethod();
                    Object result = readMethod.invoke(bean, new Object[0]);
                    returnMap.put( propertyName, result);
                }
            }
        } catch (Exception e) {
            // 解析错误时抛出服务器异常 记录日志
            throw new Exception("从bean转换为map时异常!", e);
        }
        return returnMap;
    }

    //in use
    public static <T> T convertMapToBean(Class<T> clazz,Map<String,Object> map){
        T obj = null;

        try {
            //获取bean的西悉尼?西悉尼xinxin新信息?
            BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
            obj = clazz.newInstance();
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for(int i=0;i<propertyDescriptors.length;i++){
                PropertyDescriptor descriptor = propertyDescriptors[i]; //bean内容吧
                String propertyName = descriptor.getName();
                if(map.containsKey(propertyName)){
                    Object value = map.get(propertyName);
                    if("".equals(value)){
                        value = null;
                    }
                    Object[] args = new Object[1];
                    args[0] = value;
                    descriptor.getWriteMethod().invoke(obj,args);
                }
            }

        } catch (IntrospectionException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return (T)obj;
    }




    public static <T> Map<String,Object> beanToMap(T bean){
        Map<String,Object> map = new HashMap<>();
        if (bean != null){
            BeanMap beanMap = BeanMap.create(bean);
            for(Object key : beanMap.keySet()){
                map.put(key+"",beanMap.get(key));
            }
        }
        return map;
    }


    public static <T> T mapToBean(Map<String,Object> map,Class<T> clazz)throws Exception{
        T bean = clazz.newInstance();
        BeanMap beanMap = BeanMap.create(bean);
        beanMap.putAll(map);
        return bean;
    }
}
